<?php

namespace App\Services\System;

use App\Common\Constants\CacheConst;
use App\Models\System\SysConfigModel;
use App\Validate\System\SysConfigValidate;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Cache;
use App\Common\Constants\UserConst;

/**
 * 参数配置 服务层实现
 */
class SysConfigService {

    private SysConfigModel $configModel;

    public function __construct(SysConfigModel $configModel) {
        $this->configModel = $configModel; 

        // $this->loadingConfigCache();
    }

    /**
     * 设置cache key
     * 
     * @param $configKey 参数键
     * @return 缓存键key
     */
    private function getCacheKey(string $configKey) { return CacheConst::SYS_CONFIG_KEY() . $configKey; }
    private function getCacheEx() { return now()->addDay(); }

    /**
     * 查询参数配置信息
     * 
     * @param $configId 参数配置ID
     * @return SysConfigModel 参数配置信息
     */
    public function selectConfigById(int $configId): SysConfigModel {
        return $this->configModel->selectConfig(['configId' => $configId]);
    }

    /**
     * 根据键名查询参数配置信息
     * 
     * @param $configKey 参数键名
     * @return string 参数键值
     */
    public function selectConfigByKey(string $configKey): string {
        $rk = $this->getCacheKey($configKey);

        $configValue = redis($rk);
        if (!empty($configValue)) {
            return $configValue;
        }
        $model = $this->configModel->selectConfig(['configKey' => $configKey]);
        redis([$rk => $model->config_value], $this->getCacheEx());
        return $model->config_value;
    }

    /**
     * 获取验证码开关
     * 
     * @return true开启，false关闭
     */
    public function selectCaptchaEnabled(): bool {
        $enabled = $this->selectConfigByKey('sys.account.captchaEnabled');
        return empty($enabled) ? true : boolval($enabled);
    }

    /**
     * 查询参数配置列表
     * 
     * @param $config 参数配置信息
     * @return SysConfigModel[]|Collection 参数配置集合
     */
    public function selectConfigList(array $config): Collection {
        return $this->configModel->selectConfigList($config);
    }

    /**
     * 新增参数配置
     * 
     * @param $config 参数配置信息
     * @return SysConfigModel 结果
     */
    public function insertConfig(array $config): SysConfigModel {
        $model = $this->configModel->insertConfig($config);
        $rk = $this->getCacheKey($model->config_key);
        redis([$rk => $model->config_value], $this->getCacheEx());
        return $model;
    }

    /**
     * 修改参数配置
     * 
     * @param $config 参数配置信息
     * @return int 结果
     */
    public function updateConfig(array $config): int {
        $tmp = $this->configModel->selectConfigById($config['config_id']);
        $rk = $this->getCacheKey($config['config_key']);
        if ($tmp->config_key != $config['config_key']) {
            redis()->del($rk);
        }
        $affrows = $this->configModel->updateConfig($config);
        if ($affrows > 0) {
            redis([$rk => $config['config_value']], $this->getCacheEx());
        }
        return $affrows;
    }

    /**
     * 批量删除参数信息
     * 
     * @param int[]|array $configIds 需要删除的参数ID
     */
    public function deleteConfigByIds(array $configIds): void {
        $models = $this->configModel->query()
                    ->whereIn('config_id', $configIds)
                    ->get()
                    ;
        $frameConfig = $models->filter(fn($it)=>$it->config_type == $this->configModel::IsFrame);
        if ($frameConfig->isNotEmpty()) {
            throw_str(sprintf('内置参数【%s】不能删除', $frameConfig->map(fn($it)=>$it->config_key)->join(',')));
        }
        $delrows = $this->configModel->deleteConfigByIds($configIds);
        if ($delrows > 0) {
            redis()->del($models->map(fn($it) => $it->config_key)->toArray());
        }
        
        // for (Long configId : configIds)
        // {
        //     SysConfig config = selectConfigById(configId);
        //     if (StringUtils.equals(UserConst.YES(), config.getConfigType()))
        //     {
        //         throw new ServiceException(String.format("内置参数【%1$s】不能删除 ", config.getConfigKey()));
        //     }
        //     configMapper.deleteConfigById(configId);
        //     redisCache.deleteObject(getCacheKey(config.getConfigKey()));
        // }
    }

    /**
     * 加载参数缓存数据
     */
    public function loadingConfigCache(): void {
        $this->configModel->selectConfigList([])->each(function($model) {
            redis([$this->getCacheKey($model->config_key) => $model->config_value], $this->getCacheEx());
        });
    }

    /**
     * 清空参数缓存数据
     */
    public function clearConfigCache(): int {
        dd($this->configModel->selectConfigById(1), $this->configModel->get());
        return redis(redis()->keys($this->getCacheKey('*')), 'del');
    }

    /**
     * 重置参数缓存数据
     */
    public function resetConfigCache(): void {
        $this->clearConfigCache();
        $this->loadingConfigCache();
    }

    /**
     * 校验参数键名是否唯一
     * 
     * @param array|SysConfigModel $config 参数信息
     * @return string 结果
     */
    public function checkConfigKeyUnique(array $config): string {
        $model = $this->configModel->checkConfigKeyUnique($config['configKey']);
        if ($model && $model->config_id != $config['configId']) {
            return UserConst::NOT_UNIQUE();
        }
        return UserConst::UNIQUE();
    }


}
